﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using IdeaNMR.Web.Core;
using System.Text.RegularExpressions;

namespace IdeaNMR.Web
{
    public class ListNMRObjects_BaseTable<TObj> : ListBaseObjects_BaseTable<TObj>
        where TObj : NMRObject
    {
        protected override Item[] LoadRawData()
        {
            IdeaNMRdbContainer inmr = new IdeaNMRdbContainer();
            var result = from p in inmr.BaseObjects.OfType<TObj>() // .Include("Authors").Include("NumberedAuthor.User") - this does not work
                         where !p.IsDraft && (!p.IsPrivate || p.Authors.Any(a => a.User.Username == ScrewTurnWikiFacade.Username))
                         group p by p.FirstVersion.Id into gr
                         let top = gr.FirstOrDefault(x => x.Datetime == gr.Max(y => y.Datetime))
                         select new Item
                         {
                             Obj = top,
                         };

            // I know it's disgusting, but those stupid includes are disgusting too
            
            foreach (var o in result) // For each object load Author
            {
                if (!o.Obj.Authors.IsLoaded) o.Obj.Authors.Load();

                foreach (var u in o.Obj.Authors) // for each author load user
                    if (!u.UserReference.IsLoaded) u.UserReference.Load();
            }
            return result.ToArray();
        }

        protected override Item[] FilterRawData()
        {
            IEnumerable<Item> result = base.FilterRawData();

            if (this.SearchTerms.Length > 0)
            {
                var res1 = from r in this.RawData
                           where
                              r.Obj.Authors.Any(a =>
                              Regex.IsMatch(a.User.Username.ToLowerInvariant(), this.SearchRegEx) ||
                              (!string.IsNullOrEmpty(a.User.Firstname) && Regex.IsMatch(a.User.Firstname.ToLowerInvariant(), this.SearchRegEx)) ||
                              (!string.IsNullOrEmpty(a.User.Lastname) && Regex.IsMatch(a.User.Lastname.ToLowerInvariant(), this.SearchRegEx)))
                           select r;
                result = result.Union(res1);
            }

            return result.ToArray();
        }

        protected string CreateAuthorsList(object aList)
        {
            NMRObject nmo = (NMRObject)aList;
            
            var fullNames = from a in nmo.Authors
                            orderby a.Index ascending
                            select (string.IsNullOrEmpty(a.User.Firstname) || string.IsNullOrEmpty(a.User.Lastname)) ? string.Format("({0})", a.User.Username) : a.User.Firstname + " " + a.User.Lastname;

            return string.Join("; ", fullNames.ToArray());
        }
    }
}